package com.tonann.web.threeDegree;

import com.tonann.app.VO.ProjectDeviceVO;
import com.tonann.app.domain.AppDevice;
import com.tonann.app.domain.AppFault;
import com.tonann.app.domain.AppProject;
import com.tonann.app.domain.AppSensor;
import com.tonann.app.service.IAppDeviceService;
import com.tonann.app.service.IAppFaultService;
import com.tonann.app.service.IAppProjectService;
import com.tonann.app.service.IAppSensorService;
import com.tonann.common.constant.CacheConstants;
import com.tonann.common.core.domain.AjaxResult;
import com.tonann.common.core.domain.entity.SysPlace;
import com.tonann.common.core.domain.entity.SysUser;
import com.tonann.common.utils.SecurityUtils;
import com.tonann.common.utils.StringUtils;
import com.tonann.system.service.ISysPlaceService;
import com.tonann.system.service.ISysUserService;
import com.tonann.web.vo.DeviceVO;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections4.map.HashedMap;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 登录验证
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/three")
public class ThreeDegreeController {
    @Resource
    private IAppProjectService projectService;
    @Resource
    private IAppDeviceService deviceService;

    @Resource
    private ISysUserService sysUserService;
    @Resource
    private IAppSensorService sensorService;
    @Resource
    private ISysPlaceService placeService;
    @Resource
    private IAppFaultService appFaultService;
    @Resource
    private RedisTemplate redisTemplate;

    /**
     * 获取项目信息
     *
     * @return 获取项目信息ds
     */
    @GetMapping("/getProjectInfo/{projectCode}")
    public AjaxResult getProjectInfo(@PathVariable("projectCode") String projectCode) {
        AppProject project = projectService.selectAppProjectByProjectCode(projectCode);
        return AjaxResult.success(project);
    }

    @GetMapping("/getProjectDevice/{projectCode}")
    public AjaxResult getProjectDevice(@PathVariable("projectCode") String projectCode) {
        ProjectDeviceVO vo = projectService.selectProjectDeviceByProjectCode(projectCode);
        return AjaxResult.success(vo);
    }

    @GetMapping("/getDeviceParams/{deviceId}")
    public AjaxResult getDeviceParams(@PathVariable("deviceId") String deviceId) throws Exception {
        if (deviceId != null) {
            Long id = Long.parseLong(deviceId);
            AppDevice appDevice = deviceService.selectAppDeviceByDeviceId(id);
            List<AppDevice> appDeviceList = deviceService.selectChildrenAppDeviceById(id);
            appDevice.setChildren(appDeviceList);
            DeviceVO vo = getVO(appDevice);
            getList(vo, appDevice);
            if (vo.getType().equals("1")) {
                List<DeviceVO> voList = vo.getChildrenVO();
                List<AppSensor> list = vo.getSensorList();
                if (voList != null) {
                    for (DeviceVO deviceVO : voList) {
                        list.addAll(deviceVO.getSensorList());
                    }
                }
                vo.setSensorList(list);
            }
//            List<Long> adminIds = deviceService.selectAppDeviceAdminListByDeviceId(vo.getDeviceId());
//            if (adminIds.contains(SecurityUtils.getUserId())) {
//                vo.setIsAdmin("1");
//            }
//            List<Long> operatorIds = deviceService.selectAppDeviceOperatorListByDeviceId(id);
//            if (operatorIds.contains(SecurityUtils.getUserId())) {
//                vo.setIsOperator("1");
//            }
            return AjaxResult.success(vo);
        }
        return AjaxResult.error();
    }

    private void getList(DeviceVO vo, AppDevice appDevice) throws Exception {
        List<AppDevice> appDeviceList = deviceService.selectChildrenAppDeviceById(appDevice.getDeviceId());
        if (appDeviceList != null && appDeviceList.size() > 0) {
            List<DeviceVO> voList = new ArrayList<>();
            for (AppDevice device : appDeviceList) {
                DeviceVO v = getVO(device);
                voList.add(v);
                getList(v, device);
            }
            vo.setChildrenVO(voList);
        }
    }

    private DeviceVO getVO(AppDevice appDevice) throws Exception {
        DeviceVO vo = new DeviceVO();
        BeanUtils.copyProperties(vo, appDevice);
        List<Long> placeIds = deviceService.selectAppDevicePlaceListByDeviceId(appDevice.getDeviceId());
        StringBuilder placeName = new StringBuilder();
        for (Long placeId : placeIds) {
            SysPlace place = placeService.selectPlaceById(placeId);
            if (place != null) {
                placeName.append(place.getPlaceName());
            }
        }
        List<Long> userIds = deviceService.selectAdminPhoneByDeviceId(appDevice.getDeviceId());
        List<SysUser> phones = new ArrayList<>();
        for (Long userId : userIds) {
            SysUser sysUser = sysUserService.selectUserById(userId);
            if (sysUser != null) {
                phones.add(sysUser);
            }
        }
        vo.setPosition(placeName.toString());
        vo.setPhone(phones);
        List<AppFault> faultList = appFaultService.selectUnCheckedAppFaultListByDeviceId(appDevice.getDeviceId());
        String alarm = "";
        Map<Long, AppFault> faultMap = new HashedMap<>();
        for (AppFault appFault : faultList) {
            AppFault fault = faultMap.get(appFault.getFaultRuleId());
            if (fault == null) {
                faultMap.put(appFault.getFaultRuleId(), appFault);
            } else if (appFault.getCreateTime().compareTo(fault.getCreateTime()) > 0) {
                faultMap.put(appFault.getFaultRuleId(), appFault);
            }
        }
        List<String> alarmList = new ArrayList<>();
        for (Long key : faultMap.keySet()) {
            AppFault fault = faultMap.get(key);
            if (fault != null) {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String dateStr = simpleDateFormat.format(fault.getCreateTime());
                alarm += fault.getFaultName() + ":" + dateStr;
                alarm = vo.getDeviceName() + ":" + alarm;
                alarmList.add(alarm);
            }
        }
        vo.setAlarmContent(alarmList);
        AppSensor appSensor = new AppSensor();
        appSensor.setDeviceId(appDevice.getDeviceId());
        List<AppSensor> sensorList = sensorService.selectAppSensorAllListByDeviceId(appDevice.getDeviceId());
        List<AppSensor> powerStatusSensorList = new ArrayList<>();
        List<AppSensor> appSensorLis = new ArrayList<>();
        if (!sensorList.isEmpty()) {
            for (AppSensor sensor : sensorList) {
                String s = null;
                Object object = redisTemplate.opsForValue().get(CacheConstants.APP_SENSOR_VALUE_KEY + sensor.getDeviceId() + ":sensorId:" + sensor.getSensorId());
                if (object != null) {
                    if (object instanceof String) {
                        s = object.toString();
                    }
                    if (object instanceof BigDecimal) {
                        s = ((BigDecimal) object).toString();
                    }
                }
                if (s != null) {
                    if (sensor.getSensorType().equals("4")) {
                        vo.setAirVolume(s);
                    } else if (sensor.getSensorType().equals("9")) {
                        vo.setAirSpeed(s);
                    } else if (sensor.getSensorType().equals("8") && sensor.getIsHeight() != null && sensor.getIsHeight().equals("1")) {
                        vo.setWindowHeight(s);
                    } else if (sensor.getSensorType().equals("13")) {
                        vo.setAngle(s);
                    } else if (sensor.getSensorType().equals("2")) {
                        vo.setHumidity(s);
                    } else if (sensor.getSensorType().equals("1")) {
                        vo.setTemperature(s);
                    } else if (sensor.getSensorType().equals("3")) {
                        vo.setPressure(s);
                    } else if (sensor.getSensorType().equals("6")) {
                        vo.setPowerConsumption(s);
                    } else if (sensor.getSensorType().equals("10")) {
                        vo.setFrequency(s);
                    } else if (sensor.getSensorType().equals("11")) {
                        vo.setAmpere(s);
                    } else if (sensor.getSensorType().equals("16")) {
                        vo.setTvoc(s);
                    } else if (sensor.getSensorType().equals("21")) {
                        vo.setCH2O(s);
                    } else if (sensor.getSensorType().equals("23")) {
                        vo.setO2(s);
                    } else if (sensor.getSensorType().equals("15")) {
                        vo.setNoise(s);
                    } else if (sensor.getSensorType().equals("14")) {
                        vo.setIllumination(s);
                    } else if (sensor.getSensorType().equals("20")) {
                        vo.setCO2(s);
                    } else if (sensor.getSensorType().equals("19")) {
                        vo.setPM1(s);
                    } else if (sensor.getSensorType().equals("18")) {
                        vo.setPM10(s);
                    } else if (sensor.getSensorType().equals("17")) {
                        vo.setPM2Point5(s);
                    } else if (sensor.getSensorType().equals("25")) {
                        vo.setRawWaterConductivity(s);
                    } else if (sensor.getSensorType().equals("26")) {
                        vo.setFirstWaterConductivity(s);
                    } else if (sensor.getSensorType().equals("27")) {
                        vo.setSecondWaterConductivity(s);
                    } else if (sensor.getSensorType().equals("28")) {
                        vo.setLiquidLevel(s);
                    } else if (sensor.getUnit().equals("开关量")) {
                        if (s != null) {
                            if (StringUtils.endsWith(s, ".0")) {
                                String val = StringUtils.substringBefore(s, ".0");
                                s = val;
                            }
                        }
                        if (sensor.getIsLight() != null && sensor.getIsLight().equals("1")) {
                            vo.setLight(s);
                        } else if (sensor.getIsForce() != null && sensor.getIsForce().equals("1")) {
                            vo.setForce(s);
                        } else if (sensor.getIsOn() != null && sensor.getIsOn().equals("1")) {
                            vo.setPower(s);
                            sensor.setValue(s);
                            appSensorLis.add(sensor);
                        } else if (sensor.getIsAutoDoor() != null && sensor.getIsAutoDoor().equals("1")) {
                            vo.setIsAutoDoor(s);
                        } else if (sensor.getIsBeing() != null && sensor.getIsBeing().equals("1")) {
                            vo.setIsBeing(s);
                        } else if (sensor.getWorkMode() != null && sensor.getWorkMode().equals("1")) {
                            vo.setWorkingMode(s);
                        }
                    }
                    if (sensor.getSensorType().equals("24")) {
                        sensor.setValue(s);
                    }
                } else {
                    sensor.setValue(s);
                }
                if (sensor.getSensorType().equals("24")) {
                    powerStatusSensorList.add(sensor);
                } else if (sensor.getSensorType().equals("22") && sensor.getIsOn() != null && sensor.getIsOn().equals("1") && vo.getPower() == null) {
                    vo.setPower("0");
                    vo.setIsRunning("0");
                    vo.setIsOnline("0");
                    sensor.setValue("0");
                }
                appSensorLis.add(sensor);
            }
        }
        if (powerStatusSensorList.size() > 0) {
            for (AppSensor sensor : powerStatusSensorList) {
                if (sensor.getValue() != null && !sensor.getValue().trim().equals("")) {
                    if (StringUtils.endsWith(sensor.getValue(), ".0")) {
                        String val = StringUtils.substringBefore(sensor.getValue(), ".0");
                        sensor.setValue(val);
                    }
                    vo.setPower(sensor.getValue());
                } else {
                    vo.setPower("0");
                }
            }
        }
        vo.setSensorList(appSensorLis);
        return vo;
    }

}
